package dca.sistemascontrole.view.estimacaoestado;

import dca.sistemascontrole.domain.DataObject;
import dca.sistemascontrole.view.grafico.GraphicPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;

/**
 *
 * @author Rafael
 */
public class GraficoEstimacao extends JPanel {

    private XYPlot xyplot;
    private ChartPanel pnlChart;
    private TimeSeries timeSeriesEstimado;
    private TimeSeries timeSeriesMedido;
    private TimeSeriesCollection timeSeriesCollection;
    private long maximunVisiblePeriod;
    private final Lock lock = new ReentrantLock();

    public GraficoEstimacao() {
        this("", "", "", GraphicPanel.DEFAULT_MAXIMUN_VISIBLE_PERIOD);
    }

    public GraficoEstimacao(long maximunVisibleWindow) {
        this("", "", "", maximunVisibleWindow);
    }

    public GraficoEstimacao(String title, String timeAxisLabel, String valueAxisLabel, long maximunVisibleWindow) {
        this.maximunVisiblePeriod = maximunVisibleWindow;

        setLayout(new BorderLayout());
        timeSeriesEstimado = new TimeSeries("Valor Estimado");
        timeSeriesEstimado.removeAgedItems(true);
        timeSeriesMedido = new TimeSeries("Tanque Medido");
        timeSeriesMedido.removeAgedItems(true);

        timeSeriesCollection = new TimeSeriesCollection();
        timeSeriesCollection.addSeries(timeSeriesEstimado);
        timeSeriesCollection.addSeries(timeSeriesMedido);

        JFreeChart jfreechart = createChart(timeSeriesCollection, title, timeAxisLabel, "(cm)");
        pnlChart = new ChartPanel(jfreechart);
        pnlChart.setBackground(new Color(247, 247, 247));
        pnlChart.setVisible(true);
        add(pnlChart, BorderLayout.CENTER);
    }

    public void addValue(double medido, double estimado, FixedMillisecond time) {
        try {
            lock.lock();
            TimeSeriesDataItem seriesDataItemSuperior = new TimeSeriesDataItem(time, medido);
            TimeSeriesDataItem seriesDataItemInferior = new TimeSeriesDataItem(time, estimado);

            timeSeriesEstimado.addOrUpdate(seriesDataItemSuperior);
            timeSeriesMedido.addOrUpdate(seriesDataItemInferior);
            pnlChart.revalidate();
            pnlChart.repaint();
        } finally {
            lock.unlock();
        }
    }

    public void clear() {
        timeSeriesEstimado.clear();
        timeSeriesMedido.clear();
    }

    protected JFreeChart createChart(XYDataset xydataset, String title, String timeAxisLabel, String valueAxisLabel) {
        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart(title, timeAxisLabel, valueAxisLabel, xydataset, true, true, false);
        xyplot = (XYPlot) jfreechart.getPlot();

        xyplot.setBackgroundPaint(Color.white);
        xyplot.setDomainGridlinePaint(Color.gray);
        xyplot.setRangeGridlinePaint(Color.gray);
        xyplot.setOutlineVisible(false);
        xyplot.setInsets(new RectangleInsets(0, 5, 5, 0));

        xyplot.setDomainPannable(true);
        xyplot.setRangePannable(false);
        xyplot.setDomainCrosshairVisible(true);
        xyplot.setRangeCrosshairVisible(true);

        XYItemRenderer renderer = xyplot.getRenderer();
        renderer.setSeriesPaint(0, Color.RED);
        renderer.setSeriesPaint(1, Color.BLUE);
        renderer.setSeriesPaint(2, Color.GREEN);
        renderer.setSeriesPaint(3, Color.BLACK);

        NumberAxis range = (NumberAxis) xyplot.getRangeAxis();
        range.setRange(-5.00, 30.00);

        ValueAxis valueaxis = xyplot.getDomainAxis();
        valueaxis.setAutoRange(true);
        valueaxis.setFixedAutoRange(GraphicPanel.DEFAULT_MAXIMUN_VISIBLE_PERIOD);

        jfreechart.setBackgroundPaint(Color.WHITE);

        return jfreechart;
    }

    public long getMaximunVisiblePeriod() {
        return maximunVisiblePeriod;
    }

    public void setMaximunVisiblePeriod(long maximunVisiblePeriod) {
        this.maximunVisiblePeriod = maximunVisiblePeriod;
    }

    public void setValues(List<DataObject> medidos, List<DataObject> estimados) {
        for (DataObject dataObject : medidos) {
            timeSeriesMedido.addOrUpdate(dataObject.getMillisecond(), dataObject.getValue());
        }
        
        for (DataObject dataObject : estimados) {
            timeSeriesEstimado.addOrUpdate(dataObject.getMillisecond(), dataObject.getValue());
        }
    }

    public XYPlot getXyplot() {
        return xyplot;
    }
    
    public void exibirEstimado(boolean exibir){
        if (exibir) {
            List series = timeSeriesCollection.getSeries();
            if (!series.contains(timeSeriesEstimado)) {
                timeSeriesCollection.addSeries(timeSeriesEstimado);
            }
        } else {
            timeSeriesCollection.removeSeries(timeSeriesEstimado);
        }
    }
    public void exibirMedido(boolean exibir){
        if (exibir) {
            List series = timeSeriesCollection.getSeries();
            if (!series.contains(timeSeriesMedido)) {
                timeSeriesCollection.addSeries(timeSeriesMedido);
            }
        } else {
            timeSeriesCollection.removeSeries(timeSeriesMedido);
        }
    }
}
